"""
python代码结构

#!/usr/bin/python3  # shebang行
import 模块
全局变量 规定gl_ 避免混淆
函数
main函数
if __name__ == "__main__":
    main()

"""

"""
函数基础
定义: 模块中的一个工具，封装函数避免重复应用
起名函数：见名知意、避免首字母数字用_连接
pycharm调试：函数内部用 step into 进入函数 F7
1、函数内部有num先数据引用
2、函数内部没有num发现模块有num再引用数据
3、函数内部、模块也没有变量num报错 
4、在函数内部赋值语句不会影响外部数据、但对于可变数据list、dict函数内部方法会改变外部数据
    看 函数-数据类型-变量经典.py
"""
# 问题：mypy 函数类型检测模块？


def sum _num(num1,num2):  # 上面空两行,这里num1与num2 形参
    """这是函数注释 可以用 函数名.__doc__ 显示出来 不还()哦
    :param num1: int 用于第一个计算
    :param num2: int 用于第二个计算
    """
    result = num1 + num2  # 函数一些形参 char 可以定义str、times次数、num数字
    return result

sum_num(2,4)  # 这里的2与4 实参


"""
模块基础
定义：python的核心概率
1、模块名称.py
2、import 模块（放在目录lib下）
3、导入模块后->模块名.变量  / 模块名.函数
4、导入模块后 此模块被解释器 生成 __pyc__文件 cache，模块生成二进制文件速度快，相当于gcc

"""

# 多个返回值
def text_temp_wetness():
    temp = 20
    wentness = 30
    return temp,wentness  # 返回的是一个元组 不用()
# 两个变量接下返回值
a,b = text_temp_wetness()

# 全局变量一般定义在import模块下，如果想要局部变量可以修改全局变量global关键字
import os
gl_num = 100

def text():
    a = gl_num + 1  # 在函数内部没有gl_num会引用全局变量 但不能修改

def text():
    global gl_num
    gl_num +=1  # 定义gl_num后整个模块 gl_num就会变动

# 多值参数 不确定参数有多少
def demo(num,*nums,**person):
    print(num)
    print(nums)
    print(person)
demo(1,3,4,5,6,name = "ylc",age = 18)
>>>1
>>>(3, 4, 5, 6)
>>>{'name': 'ylc', 'age': 18}


# 函数的拆包
def demo(*args,**kwargs):  # * 代表后续传递的都是元组， ** 代表后续传递的都是字典
    print(args)  # arg只是约定叫法 arguments
    print(kwargs)  # key world arguments
gl_num = (1,2,3)
gl_dict = {"name":"ylc","age":18}

demo(*gl_num,**gl_dict)  # 拆包 正确方法

demo(gl_num,gl_dict)  # 会出现
>>> (1, 2, 3)
>>> {'name': 'ylc', 'age': 18}
>>> ((1, 2, 3), {'name': 'ylc', 'age': 18})
>>> {}

# 函数技巧递归 一般用于递归路径不确定？
# 1、自己调用自己
# 2、要有函数出口，否则死循环
# 3、不同参数
# 计算 1+2+3+...+100
def sum_numbers(num):
    if num == 1 :
        return 1  # 倒过来想出口是1
    temp = sum_numbers(num-1)  # 假设sum_numbers可以正确执行 最后一次 下面return
    return temp + num  # num-1之前的和 + num
    
def log(func):
    def wrapper(*params):
        print("开始调用函数~")
        func(*params)
        print(params)
        print(*params)
        print("结束调用函数~")
    return wrapper  # 传递的是函数
@log  # 装饰器 语法糖
def eat(name,food):
    print(f"{name}开始吃东西{food}了！！！")
eat("ylc","鱼")

>>> 开始调用函数~
>>> ylc开始吃东西鱼了！！！
>>> ('ylc', '鱼')
>>> ylc 鱼
>>> 结束调用函数~